package com.piece.core.web.filter;

import com.piece.core.framework.constant.CookieConstants;
import com.piece.core.framework.constant.FrameWorkConstants;
import com.piece.core.framework.constant.HeaderConstants;
import com.piece.core.framework.constant.ParamConstants;
import com.piece.core.framework.support.convert.Convert;
import com.piece.core.framework.util.security.coder.Base64Coder;
import com.piece.core.log.config.TenantContextHolder;
import com.piece.core.framework.util.collection.ArrayUtil;
import com.piece.core.framework.util.string.StringUtil;
import com.piece.core.web.cookie.CookieUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

@Slf4j
public class TenantFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        try {
            String[] client = extractClientHeader(Convert.toStr(request.getHeader(HeaderConstants.TENANT), CookieUtil.getCookieValue(request, CookieConstants.TENANT_KET)));
            if (ArrayUtil.isNotEmpty(client)) {
                TenantContextHolder.setTenant(client[0]);
            } else {
                String clientId = request.getParameter(ParamConstants.CLIENT_ID);
                if (StringUtil.isNotEmpty(clientId)) {
                    TenantContextHolder.setTenant(clientId);
                }
            }

            chain.doFilter(request, response);
        } finally {
            TenantContextHolder.clear();
        }
    }

    private String[] extractClientHeader(String header) {
        if (null != header && header.startsWith(FrameWorkConstants.BASIC_TYPE)) {
            String clientHeaderValue = header.substring(FrameWorkConstants.BASIC_TYPE.length()).trim();
            byte[] base64Client = clientHeaderValue.getBytes(StandardCharsets.UTF_8);
            byte[] decoded = Base64Coder.decode(base64Client).getBytes();
            String clientStr = new String(decoded, StandardCharsets.UTF_8);
            String[] clientArr = clientStr.split(":");
            if (clientArr.length == 2) {
                return clientArr;
            }
        }
        return null;
    }
}
